package com.learning.spring.ioc.bean.xml.scope;

import org.springframework.context.ApplicationContext;
import org.springframework.context.support.ClassPathXmlApplicationContext;

/**
 * ClassName: BeanScope
 * Description: Bean 的Scope
 * 1、singleton：在Spring Ioc 容器中仅存在一个Bean 实例，Bean 以单例的方式存在
 * 2、prototype：多实例。每次从容器中调用Bean 时，都返回一个新的实例。即每次调用getBean()，相当于执行new XxxBean
 * <p>
 * Spring web 增加的 Scope，仅适用于 WebApplicationContext
 * 3、request：每次Http请求都会创建一个新的 Bean。
 * 4、session：同一个Http session 共享一个 Bean。不同的 http Session 使用不同的 Bean
 * 5、global session：同一个全局的 Session 共享一个bean，一般用于 Portlet 应用环境
 * Date: 2018/7/26 9:49 【需求编号】
 *
 * @author Sam Sho
 * @version V1.0.0
 */
public class BeanScope {
    public static void main(String[] args) {
//        testSingleton();
        testPrototype();
    }

    /**
     * 默认是 singleton，单例
     */
    static void testSingleton() {
        // 手动初始化Bean容器
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
        ScopeBean singletonBean = context.getBean("singletonBean", ScopeBean.class);
        ScopeBean singletonBean1 = context.getBean("singletonBean", ScopeBean.class);

        // true , 被实例化2次
        System.out.println(singletonBean == singletonBean1);

        /*
        调用了ScopeBean的构造函数
        true
        */
    }

    /**
     * 添加 scope="prototype"
     */
    static void testPrototype() {
        // 手动初始化Bean容器
        ApplicationContext context = new ClassPathXmlApplicationContext("spring-context.xml");
        ScopeBean prototypeBean = context.getBean("prototypeBean", ScopeBean.class);
        ScopeBean prototypeBean2 = context.getBean("prototypeBean", ScopeBean.class);

        // false
        System.out.println(prototypeBean == prototypeBean2);

        /*
         调用了ScopeBean的构造函数
         调用了ScopeBean的构造函数
         false
         */
    }

    /**
     * Web 应用相关的 Bean 作用域：
     * 1. 配置 RequestContextListener 监听器，该监听器实现 ServletRequestListener，监听
     */
    static void test2() {

    }
}
